from django.shortcuts import render, redirect
from .models import Publisher, Author, Book
import requests
from bs4 import BeautifulSoup
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger


# 封装分页功能
def get_paginator(request, list_article, per_page_num=1):
    """
    分页功能的实现
    :param request: 全局请求对象
    :param list_article: 要分页的文章列表
    :param per_page_num: 每页的文章数量
    :return: 查询页的文章列表
    """
    page = request.GET.get('page', '1')
    paginator = Paginator(list_article, per_page_num)
    nums = []
    # 中间页
    try:
        page = int(page)
        page_count = paginator.num_pages
        if page < page_count - 9:
            nums = paginator.page_range[page:page + 10]
        else:
            nums = paginator.page_range[page:page_count + 1]
    except Exception as e:
        print(e)
    try:
        list = paginator.page(page)
    except PageNotAnInteger:
        list = paginator.page(1)
    except EmptyPage:
        list = paginator.page(paginator.num_pages)
    return list, nums


# 用户代理池
def get_headers():
    user_agent_list = [
        'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.8) Gecko Fedora/1.9.0.8-1.fc10 Kazehakase/0.5.6',
        'Mozilla/5.0 (X11; Linux i686; U;) Gecko/20070322 Kazehakase/0.4.5',
        'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.71 Safari/537.1 LBBROWSER',
        'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)',
        'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11',
        'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11',
        'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; QQDownload 732; .NET4.0C; .NET4.0E)',
        'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11',
        'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; SV1; QQDownload 732; .NET4.0C; .NET4.0E; 360SE)',
        'Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 5.2; .NET CLR 1.1.4322; .NET CLR 2.0.50727; InfoPath.2; .NET CLR 3.0.04506.30)',
        'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/535.20 (KHTML, like Gecko) Chrome/19.0.1036.7 Safari/535.20',
        'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.8) Gecko Fedora/1.9.0.8-1.fc10 Kazehakase/0.5.6',
        'Mozilla/5.0 (X11; U; Linux x86_64; zh-CN; rv:1.9.2.10) Gecko/20100922 Ubuntu/10.10 (maverick) Firefox/3.6.10',
        'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.71 Safari/537.1 LBBROWSER',
        'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.89 Safari/537.1',
        'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; Acoo Browser; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.0.04506)',
        'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.0.12) Gecko/20070731 Ubuntu/dapper-security Firefox/1.5.0.12',
        'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; QQDownload 732; .NET4.0C; .NET4.0E; LBBROWSER)',
        'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.89 Safari/537.1',
        'Mozilla/5.0 (iPhone; CPU iPhone OS 10_3 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.3 Mobile/14E277 Safari/603.1.30',
        'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36',
        'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)',
        'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Avant Browser)',
        'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; 360SE)',
        'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; SE 2.X MetaSr 1.0; SE 2.X MetaSr 1.0; .NET CLR 2.0.50727; SE 2.X MetaSr 1.0)',
        'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; The World)',
        'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)',
        'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; TencentTraveler 4.0)',
        'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Maxthon 2.0)',
        'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_0) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11',
        'Opera/9.80 (Windows NT 6.1; U; en) Presto/2.8.131 Version/11.11',
        'Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; en) Presto/2.8.131 Version/11.11',
        'Mozilla/5.0 (Windows NT 6.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1',
        'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)',
        'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)',
        'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)',
        'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)',
        'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50',
        'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50',
        'Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_3_3 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8J2 Safari/6533.18.5',
        'Mozilla/5.0 (iPod; U; CPU iPhone OS 4_3_3 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8J2 Safari/6533.18.5',
        'Mozilla/5.0 (iPad; U; CPU OS 4_3_3 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8J2 Safari/6533.18.5',
        'Mozilla/5.0 (Linux; U; Android 2.3.7; en-us; Nexus One Build/FRF91) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1',
        'MQQBrowser/26 Mozilla/5.0 (Linux; U; Android 2.3.7; zh-cn; MB200 Build/GRJ22; CyanogenMod-7) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1',
        'Opera/9.80 (Android 2.3.4; Linux; Opera Mobi/build-1107180945; U; en-GB) Presto/2.8.149 Version/11.10',
        'Mozilla/5.0 (Linux; U; Android 3.0; en-us; Xoom Build/HRI39) AppleWebKit/534.13 (KHTML, like Gecko) Version/4.0 Safari/534.13',
        'Mozilla/5.0 (BlackBerry; U; BlackBerry 9800; en) AppleWebKit/534.1+ (KHTML, like Gecko) Version/6.0.0.337 Mobile Safari/534.1+',
        'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.75 Safari/537.36',
        'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)',
        'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.3; .NET4.0C; .NET4.0E) QQBrowser/6.9.11079.201',
        'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/13.0.782.41 Safari/535.1 QQBrowser/6.9.11079.201',
        'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.3; .NET4.0C; .NET4.0E)',
        'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.3 (KHTML, like Gecko) Chrome/6.0.472.33 Safari/534.3 SE 2.X MetaSr 1.0',
        'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.3; .NET4.0C; .NET4.0E; SE 2.X MetaSr 1.0)',
        'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.3; .NET4.0C; .NET4.0E)',
        'Mozilla/5.0 (Windows; U; Windows NT 6.1; ) AppleWebKit/534.12 (KHTML, like Gecko) Maxthon/3.0 Safari/534.12',
        'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)',
        'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)',
        'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; GTB7.0)',
        'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; InfoPath.3)',
        'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0; .NET CLR 2.0.50727; SLCC2; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.3; .NET4.0C; Tablet PC 2.0; .NET4.0E)',
        'Opera/9.80 (Windows NT 6.1; U; zh-cn) Presto/2.9.168 Version/11.50',
        'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50',
        'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0) Gecko/20100101 Firefox/6.0',
        'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.163 Safari/535.1',
    ]
    from random import randint
    headers = {"User-Agent": user_agent_list[randint(0, len(user_agent_list) - 1)]}
    return headers


# Create your views here.
def index(request):
    publisher_list = Publisher.objects.all()
    # 获取分页数据 得到分页列表,中间页列表
    list, nums = get_paginator(request, publisher_list, 5)
    return render(request, 'day62/index.html', locals())


# 出版社列表
def publisher_list(request):
    publishers = Publisher.objects.all()
    list, nums = get_paginator(request, publishers, 5)
    return render(request, 'day62/publisher_list.html', locals())


def publisher_add(request):
    # if request.method == 'POST':
    new_publisher_name = request.POST.get('publisher_name')
    if new_publisher_name and not Publisher.objects.filter(name=new_publisher_name):
        Publisher.objects.create(name=new_publisher_name)
        return redirect('/publisher/list.html')
    # return render(request, 'book/publisher_add.html', locals())


def publisher_delete(request):
    pid = request.GET.get('pid')
    try:
        Publisher.objects.get(id=pid).delete()
    except Exception as e:
        print(e)
    return redirect('/publisher/list.html')


def publisher_edit(request):
    """
    修改出版社
    :param request:
    :return:
    """
    pid = request.GET.get('pid')
    try:
        publisher = Publisher.objects.get(id=pid)
    except Exception as e:
        print(e)
    if request.method == 'POST':
        new_publisher_name = request.POST.get('publisher_name')
        pid = int(request.POST.get('pid'))
        # 更新数据 1 找到索引  2 根据索引修改
        if new_publisher_name and not Publisher.objects.filter(name=new_publisher_name):
            # 更新三步走 查询 赋值  保存
            publisher = Publisher.objects.get(id=pid)
            publisher.name = new_publisher_name
            # Publisher.objects.create(name=new_publisher_name)
            publisher.save()
            return redirect('/publisher/list.html')
    return render(request, 'day62/publisher_edit.html', locals())


def publisher_search(request):
    """
    搜索出版社
    :param request:
    :return:
    """
    publisher_name = request.POST.get('publisher_name', '')
    publishers = Publisher.objects.filter(name__contains=publisher_name)
    list, nums = get_paginator(request, publishers, 10)
    return render(request, 'day62/publisher_list.html', locals())


# 一键获取中国图书网所有出版社名字
def publisher_spider(request):
    html = requests.get(url='http://www.bookschina.com/books/publish/',
                        headers=get_headers())
    soup = BeautifulSoup(html.text)
    print(soup)
    publisher_list = soup.select('.publisherList tbody tr td a')
    for publisher in publisher_list:
        # print(publisher)
        # print(publisher.get_text())
        new_publisher_name = publisher.get_text()
        if not Publisher.objects.filter(name=new_publisher_name):
            Publisher.objects.create(name=new_publisher_name)
    return redirect('/publisher/list.html')


# 图书对应的路由
def book_list(request):
    books = Book.objects.all().order_by('-id')
    list, nums = get_paginator(request, books, 5)
    return render(request, 'day62/book_list.html', locals())


def book_add(request):
    # title author publisher  start_price  now_price
    title = request.POST.get('title')
    author = request.POST.get('author')
    publisher = request.POST.get('publisher')
    start_price = request.POST.get('start_price')
    now_price = request.POST.get('now_price')
    # 对价格做检查
    try:
        float(start_price)
        float(now_price)
        start_price = '¥' + start_price
        now_price = '¥' + now_price
    except Exception as e:
        print(e)
        print('价格格式不正确')
    # 先检查作者和出版社是否已存在 再保存
    if Author.objects.filter(name=author):
        author = Author.objects.filter(name=author).first()
    else:
        author = Author(name=author)
        author.save()
    if Publisher.objects.filter(name=publisher):
        publisher = Publisher.objects.filter(name=publisher).first()
    else:
        publisher = Publisher(name=publisher)
        publisher.save()
    if Book.objects.filter(title=title):
        print('该书已存在')
    else:
        Book.objects.create(title=title, author=author, publisher=publisher,
                            start_price=start_price, now_price=now_price)
    return redirect('/book/list.html')


def book_edit(request):
    bid = request.GET.get('bid')
    book = Book.objects.get(id=int(bid))
    return render(request, 'day62/book_edit.html', locals())


def book_delete(request):
    bid = request.GET.get('bid')
    try:
        Book.objects.get(id=bid).delete()
    except Exception as e:
        print(e)
    return redirect('/book/list.html')


def book_search(request):
    title = request.POST.get('title', '')
    books = Book.objects.filter(title__contains=title)
    list, nums = get_paginator(request, books, 10)
    return render(request, 'day62/book_list.html', locals())


def book_spider(request):
    """
    一键更新所有图书
    :return: None
    """
    html = requests.get('http://www.bookschina.com/24hour/', headers=get_headers())
    # print(html.status_code)
    soup = BeautifulSoup(html.text, features='html.parser')
    book_list = soup.select('div.bookList ul li')
    # print(book_list)
    # 得到图书列表 提取信息
    for book in book_list:
        # print(book)
        # title = book.select('div.cover a')[0].get('title')
        # print(title)
        # book_img = book.select('div.cover a img')[0].get('src')
        # print(book_img)
        # author = book.select('div.author a')[0].get_text()
        # print(author)
        # publisher = book.select('div.publisher a')[0].get_text()
        # print(publisher)
        # start_price = book.select('div.priceWrap del')[0].get_text()
        # print(start_price)
        # now_price = book.select('div.priceWrap span.sellPrice')[0].get_text()
        # print(now_price)
        # break
        try:
            title = book.select('div.cover a')[0].get('title')
            book_img = book.select('div.cover a img')[0].get('src')
            # print(title)
            # print(book_img)
            # break
            # author start_price now_price
            author = book.select('div.author a')[0].get_text()
            publisher = book.select('div.publisher a')[0].get_text()
            # print(book.select('div.publisher a')[0].get_text())
            # print(publisher)
            start_price = book.select('div.priceWrap del')[0].get_text()
            now_price = book.select('div.priceWrap span.sellPrice')[0].get_text()
            # print(start_price)
            # print(now_price)
            # break
            # 测试
            print(title)
            print(author)
            print(publisher)
            print(book_img)
            print(start_price)
            print(now_price)
            # 检查出版社是否已存在 不存在就添加
            res = Publisher.objects.filter(name=publisher.strip())
            print('正在检查出版社是否存在...')
            if not res:
                publisher = Publisher(name=publisher)
                publisher.save()
            else:
                publisher = Publisher.objects.filter(name=publisher.strip()).first()

            # 检查作者是否已存在 不存在就添加
            author_name = author.strip()
            print('正在检查作者是否存在...')
            res = Author.objects.filter(name=author_name)
            if not res:
                author = Author(name=author_name)
                author.save()
            else:
                author = Author.objects.filter(name=author_name.strip()).first()
            print('正在更新数据库数据...')
            # 检查图书是否存在
            if not Book.objects.filter(title=title):
                Book.objects.create(title=title, author=author, publisher=publisher,
                                    book_img=book_img, start_price=start_price,
                                    now_price=now_price)
            else:
                print('<<{}>>已存在'.format(title))
            print('添加了一条新的数据...')

        except Exception as e:
            print(e)
            continue
    return redirect('/book/list.html')


# 作者对应的视图
def author_add(request):
    author_name = request.POST.get('author_name')
    if Author.objects.filter(name=author_name):
        print('作者已存在')
    else:
        Author.objects.create(name=author_name)
    return redirect('/author/list.html')


def author_delete(request):
    id = request.GET.get('id')
    try:
        Author.objects.get(id=int(id)).delete()
    except Exception as e:
        print(e)
        print('不存在该用户')
    return redirect('/author/list.html')


def author_edit(request):
    if request.method == 'POST':
        id = request.POST.get('id')
        author_name = request.POST.get('author_name')
        if Author.objects.filter(name=author_name):
            print('该用户名已存在')
        else:
            try:
                author = Author.objects.get(id=int(id))
                author.name = author_name
                author.save()
            except Exception as e:
                print(e)
    else:
        id = request.GET.get('id')
        try:
            author = Author.objects.get(id=int(id))
        except Exception as e:
            print(e)
    return render(request, 'day62/author_edit.html', locals())


def author_list(request):
    authors = Author.objects.all().order_by('-id')
    list, nums = get_paginator(request, authors, 10)
    return render(request, 'day62/author_list.html', locals())


def author_search(request):
    author_name = request.POST.get('author_name', '')
    authors = Author.objects.filter(name__contains=author_name).order_by('-id')
    list, nums = get_paginator(request, authors, 3)
    return render(request, 'day62/author_list.html', locals())


def author_books(request):
    id = request.GET.get('id', '')
    try:
        aurhor = Author.objects.get(id=int(id))
        books = aurhor.get_books()
        list, nums = get_paginator(request, books, 3)
        return render(request, 'day62/book_list.html', locals())
    except Exception as e:
        print(e)
